(define (length l)
  (let loop ((l l) (len 0))
    (if (null? l) len (loop (cdr l) (+ len 1)))))

(define (map f l)
  (if (null? l)
      '()
      (cons (f (car l))
            (map f (cdr l)))))

(define (for-each proc l)
  (if (null? l)
      #t
      (begin (proc (car l))
	     (for-each proc (cdr l)))))

(define (foldl f a xs)
  (if (null? xs)
      a
      (foldl f (f a (car xs)) (cdr xs))))

(define (append x y)
  (if (null? x)
      y
      (cons (car x) (append (cdr x) y))))

(define (revappend l r)
  (if (null? l)
      r
      (revappend (cdr l) (cons (car l) r))))

(define (reverse l) (revappend l '()))

(define (filter p l)
  (if (null? l)
      '()
      (if (p (car l))
          (cons (car l) (filter p (cdr l)))
          (filter p (cdr l)))))

(define (concat-map func lst)
  (if (null? lst)
      '()
      (append (func (car lst))
              (concat-map func (cdr lst)))))

(define (concatenate lists) (concat-map (lambda (i) i) lists))

(define (member elt lst)
 (if (null? lst) #f (or (eq? elt (car lst)) (member elt (cdr lst)))))

(define (copy-list l) (map (lambda (i) i) l))

(define (fold kons knil lst)
  (if (null? lst)
      knil
      (kons (car lst)
	    (fold kons knil (cdr lst)))))

(define (index nm lst)
  (let loop ((i 0) (lst lst))
    (if (null? lst)
	#f
	(if (eq? nm (car lst))
	    i
	    (loop (+ i 1) (cdr lst))))))
